#include "ESP01s_Control.h"
#include "Delay.h"

// 状态变量
static int retry_count = 0;
static int max_retry = 5;

// 指令变量
char payload[64];
//char usrname[16];
//char passwd[16];

// 创建传感器任务句柄
TaskHandle_t xSensorDataHandle = NULL;

//// 初始化 payload
//void ESP_BuildPayload(void) {
//    char payload[64];
//    snprintf(payload, sizeof(payload), "AT+CWJAP_DEF=\"%s\",\"%s\"\r\n", usrname, passwd);
//}

void ESP_AutoConnect(void) {
	USART_printf(&USART1_Cfg, "[TEST]esp.ctrl.c line24 | esp_state: %d \r\n", ESP_state);
    ESP_state = ESP_STATE_IDLE;
	
	OLED_Clear();
	OLED_ShowString(1, 1, "(^v^)/ hello!");
    OLED_ShowString(2, 1, "ESP AUTO START");

//	USART_SendString(&USART2_Cfg, (const unsigned char*)"AT+CWMODE_DEF=1\r\n", strlen("AT+CWMODE_DEF=1\r\n"));  // 发送第一条AT指令
//	USART_ClearRDR(&USART2_Cfg);
    USART_SendString(&USART2_Cfg, (const unsigned char*)"AT+CWJAP?\r\n", strlen("AT+CWJAP?\r\n"));  // 发送第一条AT指令
}

/**
 * @brief  检查esp-01s的状态，并且实现重新联网
 * @param  msg.data
 * @retval 无
 * @note   代码的吐槽注释不要写太长，不然会无缘无故收不到esp-01s信息，真是太狗了。
 */
void ESP_StateTransition(char *resp) {
    USART_printf(&USART1_Cfg, "[TEST]esp.ctrl.c line43 | esp_state: %d \r\n", ESP_state);
	
	if(ESP_state == 0){
		static int ok_flag = -1;
		if(strncmp(resp, "No AP", 5) == 0){	
			ok_flag = 0;
			USART_printf(&USART1_Cfg, "[TEST]esp.ctrl.c line46 | esp_state: %d \r\n", ESP_state);
	//		while(strncmp(resp, "OK", 2) != 0){
	//			vTaskDelay(500);
	//		}
	//		USART_printf(&USART1_Cfg, "[TEST]esp.ctrl.c line48 | esp_state: %d \r\n", ESP_state);

		}
		else if(strncmp(resp, "+CWJAP:", 7) == 0 || strncmp(resp, "WIFI CONNECTED", 14) == 0){
			ok_flag = 1;
		}
		else if(strncmp(resp, "OK", 2) == 0 && ok_flag == 0){
			SendWiFiCredentials();
			SYS_BLLED_shortBlink();
		}
		else if(strncmp(resp, "OK", 2) == 0 && ok_flag == 1){
			StartTCPConnection();
			SYS_BLLED_shortBlink();
		}
	}
	else if (ESP_state == 1 && strncmp(resp, "OK", strlen("OK")) == 0) {
		USART_printf(&USART1_Cfg, "[TEST]esp.ctrl.c line98 | esp_state: %d \r\n", ESP_state);
		
		StartTCPConnection();
		SYS_BLLED_shortBlink();
	}

//	else if (ESP_state == 2 && (strncmp(resp, "CONNECT", 7) == 0) {
	else if (ESP_state == 2 && (strncmp(resp, "OK", strlen("OK")) == 0 || strncmp(resp, "ALREADY CONNECTED", strlen("ALREADY CONNECTED")) == 0)) {
	USART_printf(&USART1_Cfg, "[TEST]esp.ctrl.c line103 | esp_state: %d \r\n", ESP_state);
		EnableTransparentMode();
		SYS_BLLED_shortBlink();
	}
	else if (ESP_state == 3 && strncmp(resp, "OK", 2) == 0) {
		USART_printf(&USART1_Cfg, "[TEST]esp.ctrl.c line108 | esp_state: %d \r\n", ESP_state);
		
		PrepareToSend();
		SYS_BLLED_shortBlink();
	}
//	else if (ESP_state == 4 && strncmp(resp, ">", 1) == 0) {
	else if (ESP_state == 4 && strncmp(resp, "OK", 2) == 0) {
		USART_printf(&USART1_Cfg, "[TEST]esp.ctrl.c line113 | esp_state: %d \r\n", ESP_state);
		
		EnterHTTPMode();
		SYS_BLLED_shortBlink();
	}
	
	else if (strncmp(resp, "HTTP/1.1 200 OK", 15) == 0) {
		USART_printf(&USART1_Cfg, "[TEST]esp.ctrl.c line58 | esp_state: %d \r\n", ESP_state);
		
//        ESP_index = 5;
		ESP_state = ESP_STATE_HTTP_CONNECT;

		EnterHTTPMode();
		return;
	}
	
	else if ((strncmp(resp, "FAIL", 4) == 0 || strncmp(resp, "ERROR", 5) == 0) || strncmp(resp, "CLOSED", 6) == 0) { /* 失败响应处理 */
		USART_printf(&USART1_Cfg, "[TEST]esp.ctrl.c line68 | esp_state: %d \r\n", ESP_state);
	
		SYS_RLED_shortBlink();
		if (++retry_count < max_retry) {	// 延时后重发当前指令
			//	USART_printf(&USART1_Cfg, "[TEST]esp.ctrl.c line62\r\n");

			vTaskDelay(pdMS_TO_TICKS(1000));
			SendCurrentCommand();
			return;
			
		} else {       						// 彻底失败时重置
			//	USART_printf(&USART1_Cfg, "[TEST]esp.ctrl.c line68\r\n");
			
			ResetConnection(); 
			return;
		}
	}
	
//	USART_printf(&USART1_Cfg, "[TEST]esp.ctrl.c line158 | esp_state: %d \r\n", ESP_state);
//    memset(resp, 0, strlen(resp));
}

/*--------------- 状态动作封装函数 ---------------*/

static void SendWiFiCredentials(void) {
	USART_printf(&USART1_Cfg, "[TEST]esp.ctrl.c line164 | esp_state: %d \r\n", ESP_state);
	
    retry_count = 0;
	
    snprintf(payload, sizeof(payload), "AT+CWJAP_DEF=\"%s\",\"%s\"\r\n", usrname, passwd);
	USART_SendString(&USART2_Cfg, (const unsigned char*)payload, strlen(payload));
    ESP_state = ESP_STATE_WIFI_CONNECT;
    UpdateOLED("Connecting WiFi...");
}

static void StartTCPConnection(void) {
	USART_printf(&USART1_Cfg, "[TEST]esp.ctrl.c line175 | esp_state: %d \r\n", ESP_state);
    
	retry_count = 0;
	
	USART_SendString(&USART2_Cfg, (const unsigned char*)"AT+CIPSTART=\"TCP\",\"47.111.20.8\",9080\r\n", strlen("AT+CIPSTART=\"TCP\",\"47.111.20.8\",9080\r\n"));
    ESP_state = ESP_STATE_TCP_CONNECT;
    UpdateOLED("Starting TCP...");
}

static void EnableTransparentMode(void) {
	USART_printf(&USART1_Cfg, "[TEST]esp.ctrl.c line185 | esp_state: %d \r\n", ESP_state);
	
    retry_count = 0;

	USART_SendString(&USART2_Cfg, (const unsigned char*)"AT+CIPMODE=1\r\n", strlen("AT+CIPMODE=1\r\n"));
    ESP_state = ESP_STATE_TX_PREPARE;
    UpdateOLED("Enabling Transparent...");
}

static void PrepareToSend(void) {
	USART_printf(&USART1_Cfg, "[TEST]esp.ctrl.c line195 | esp_state: %d \r\n", ESP_state);
	
    retry_count = 0;

	USART_SendString(&USART2_Cfg, (const unsigned char*)"AT+CIPSEND\r\n", strlen("AT+CIPSEND\r\n"));
    ESP_state = ESP_STATE_TRANSPARENT;
    UpdateOLED("Pre for HTTP...");
}

static void EnterHTTPMode(void) {
	USART_printf(&USART1_Cfg, "[TEST]esp.ctrl.c line205 | esp_state: %d \r\n", ESP_state);
	
	retry_count = 0;

	ESP_state = ESP_STATE_HTTP_CONNECT;
	UpdateOLED("AUTO READY!");
	
    if (xSensorDataHandle == NULL) {
        xTaskCreate(vTask_ESP01s_SensorData_Push, "SensorPush", 128, NULL, 1, &xSensorDataHandle);
    }
}

static void ResetConnection(void) {
	USART_printf(&USART1_Cfg, "[TEST]esp.ctrl.c line218 | esp_state: %d \r\n", ESP_state);
	
    retry_count = 0;
    ESP_state = ESP_STATE_IDLE;
	
    UpdateOLED("Resetting...");
    vTaskDelay(pdMS_TO_TICKS(1000));
    ESP_AutoConnect(); // 重新触发初始连接
}

/*--------------- 辅助函数 ---------------*/

static void SendCurrentCommand(void) {
	USART_printf(&USART1_Cfg, "[TEST]esp.ctrl.c line237 | esp_state: %d \r\n", ESP_state);
	
	switch(ESP_state){
		case 0: ESP_AutoConnect(); break;
		case 1: SendWiFiCredentials(); break;
		case 2: StartTCPConnection(); break;
		case 3: EnableTransparentMode(); break;
		case 4: PrepareToSend(); break;
		case 5: EnterHTTPMode(); break;
		case 6: ResetConnection(); break;
		default:break;
	}
	UpdateOLED("Retrying...");
}

static void UpdateOLED(const char *msg) {
	static char state[8];
	switch(ESP_state){
		case 0: strcpy(state,"IDE"); break;
		case 1: strcpy(state,"WIFI"); break;
		case 2: strcpy(state,"TCP"); break;
		case 3: strcpy(state,"TX"); break;
		case 4: strcpy(state,"TRANS"); break;
		case 5: strcpy(state,"HTTP"); break;
		case 6: strcpy(state,"ERROR"); break;
	}
	
    OLED_Clear();
    OLED_ShowString(1, 1, "ESP STATE");
    OLED_ShowString(2, 1, (const char*)state);
    OLED_ShowString(3, 1, msg);
}

/*--------------- 发送传感器状态 ---------------*/
void vTask_ESP01s_SensorData_Push(void *arg) {
    USART_printf(&USART1_Cfg, "[TEST]esp.ctrl.c line276\r\n");
	
    while (ESP_state == ESP_STATE_HTTP_CONNECT) { // 增加状态判断
        ESP_SendPacket();

        SYS_BLLED_shortBlink();
        vTaskDelay(pdMS_TO_TICKS(20000)); // 建议用宏保证可读性
    }

    vTaskDelete(NULL); // 自动删除任务
}

void ESP_SendPacket(void) {
	USART_printf(&USART1_Cfg, "[TEST]esp.ctrl.c line293\r\n");
	
    char payload[MAX_MSG_LEN];

    // 1. 采集数据
    uint16_t adc_val = AD_GetValue(ADC_Channel_1);
    int payload_len = snprintf(payload, sizeof(payload), "GET /0 HTTP/1.1\r\nuser-agent: STM32\r\n\r\n[PESS CH1:%d]",
                               adc_val);

    // 2. 发送数据至服务器
    payload[payload_len] = '\0';
    USART_SendString(&USART2_Cfg, (const unsigned char*)payload, strlen(payload));

    // 3. 发送数据至OLED
    OLED_Clear();
    OLED_ShowString(1, 1, "PESS CH1:");
    OLED_ShowUnsignedNum(2, 1, adc_val, 4);

    // 4. 根据传感器反馈值控制小灯
    if (adc_val >= 2000) {
        GPIO_WriteBit(SNR_LED_PORT, SNR_LED_PIN, (BitAction)LED_OFF);
    } else {
        GPIO_WriteBit(SNR_LED_PORT, SNR_LED_PIN, (BitAction)LED_ON);
    }
}
